import { AxiosTransform } from '@/http/axios/axiosTransform';
import { AxiosRequestConfig, AxiosResponse } from 'axios';
import { CreateAxiosOptions, RequestOptions, Result } from '@/http/axios/type';
import { ContentTypeEnum, ResultEnum } from '@/http/enums/httpEnums';
import { errorHandle } from '@/http/axios/errorHandle';
import { isString } from '@/utils/is';
import { getToken } from '@/http/auth';
import { VAxios } from '@/http/axios/Axios';
import { deepMerge } from '@/utils';

const transform: AxiosTransform = {
  transformRequestData: (res: AxiosResponse<Result>, options: RequestOptions) => {
    const { isTransformRequestResult } = options;
    if (!isTransformRequestResult) {
      return res.data;
    }
    const errorResult = undefined;
    const result = res?.data;

    if (!result) {
      return errorResult;
    }

    const { code, data, msg } = result;
    const hasSuccess = code === ResultEnum.SUCCESS || code === ResultEnum.OTHER_SUCCESS;

    if (hasSuccess) {
      return data || true;
    }
    errorHandle(code, msg);
    return errorResult;
  },
  beforeRequestHook: (config: AxiosRequestConfig, options: RequestOptions) => {
    const { apiUrl, prefixUrl } = options;
    if (prefixUrl) {
      config.url = `${prefixUrl}${config.url}`;
    }
    if (apiUrl && isString(apiUrl)) {
      config.url = `${apiUrl}${config.url}`;
    }
    return config;
  },
  requestInterceptors: (config: AxiosRequestConfig) => {
    const token = getToken();
    if (token) {
      config.headers.Authorization = 'Bearer ' + token;
    }
    return config;
  },
  responseInterceptorsCatch: (error: any) => {
    return error;
  }
};

function createAxios(opt?: Partial<CreateAxiosOptions>) {
  return new VAxios(
    deepMerge({
      timeout: 10 * 1000,
      headers: { 'Content-Type': ContentTypeEnum.JSON },
      transform,
      requestOptions: {
        prefixUrl: '/gateway',
        isTransformRequestResult: true,
        apiUrl: ''
      }
    }, opt || {})
  );
}

export const apiDefault = createAxios();
